package com.trace.demo.controller;

import com.trace.demo.annotation.OperationLog;
import com.trace.demo.dto.ProductDTO;
import com.trace.demo.entity.FarmingActivity;
import com.trace.demo.entity.Product;
import com.trace.demo.entity.User;
import com.trace.demo.repository.FarmingActivityRepository;
import com.trace.demo.repository.ProductRepository;
import com.trace.demo.repository.UserRepository;
import com.trace.demo.response.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 产品控制器
 */
@RestController
@RequestMapping("/api/products")
public class ProductController {

    private final ProductRepository productRepository;
    private final UserRepository userRepository;
    private final FarmingActivityRepository activityRepository;

    @Autowired
    public ProductController(ProductRepository productRepository,
                             UserRepository userRepository,
                             FarmingActivityRepository activityRepository) {
        this.productRepository = productRepository;
        this.userRepository = userRepository;
        this.activityRepository = activityRepository;
    }

    /**
     * 获取产品列表（分页）
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @param farmerId 农户ID（可选）
     * @param category 产品类别（可选）
     * @param name 产品名称（可选）
     * @param batchId 批次ID（可选）
     * @param batchNumber 批次号（可选，向后兼容）
     * @param sortBy 排序字段
     * @param sortDir 排序方向
     * @return 分页产品列表
     */
    @GetMapping
    @OperationLog(module = "产品管理", action = "查询", description = "获取产品列表")
    public ResponseEntity<?> getProducts(
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize,
            @RequestParam(required = false) Long farmerId,
            @RequestParam(required = false) String category,
            @RequestParam(required = false) String name,
            @RequestParam(required = false) String batchId,
            @RequestParam(required = false) String batchNumber,
            @RequestParam(defaultValue = "id") String sortBy,
            @RequestParam(defaultValue = "desc") String sortDir) {

        try {
            // 创建排序
            Sort sort = sortDir.equalsIgnoreCase("asc") ?
                    Sort.by(sortBy).ascending() :
                    Sort.by(sortBy).descending();

            // 创建分页
            Pageable pageable = PageRequest.of(pageNum - 1, pageSize, sort);

            // 创建动态查询条件
            Specification<Product> spec = (root, query, criteriaBuilder) -> {
                List<Predicate> predicates = new ArrayList<>();

                // 如果指定了农户ID
                if (farmerId != null) {
                    predicates.add(criteriaBuilder.equal(root.get("farmerId"), farmerId));
                }

                // 如果指定了产品类别
                if (category != null && !category.isEmpty()) {
                    predicates.add(criteriaBuilder.equal(root.get("category"), category));
                }

                // 如果指定了产品名称
                if (name != null && !name.isEmpty()) {
                    predicates.add(criteriaBuilder.like(root.get("name"), "%" + name + "%"));
                }

                // 如果指定了批次ID
                if (batchId != null && !batchId.isEmpty()) {
                    predicates.add(criteriaBuilder.like(root.get("batchId"), "%" + batchId + "%"));
                }

                // 如果指定了批次号
                if (batchNumber != null && !batchNumber.isEmpty()) {
                    predicates.add(criteriaBuilder.like(root.get("batchNumber"), "%" + batchNumber + "%"));
                }

                return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
            };

            // 获取分页数据
            Page<Product> page = productRepository.findAll(spec, pageable);

            // 转换为DTO
            List<ProductDTO> productDTOs = page.getContent().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());

            // 创建分页响应，符合前端期望的格式
            Map<String, Object> pageData = new HashMap<>();
            pageData.put("content", productDTOs);  // 使用content作为key以匹配前端期望
            pageData.put("totalElements", page.getTotalElements());
            pageData.put("totalPages", page.getTotalPages());
            pageData.put("size", page.getSize());
            pageData.put("number", page.getNumber());

            // 调试日志
            System.out.println("Returning product DTOs with fields: " +
                String.join(", ", productDTOs.stream()
                    .findFirst()
                    .map(dto -> dto.toString())
                    .orElse("No products found")));

            // 使用ApiResponse包装，确保有success和message字段
            return ResponseEntity.ok(new ApiResponse<>(true, "获取产品列表成功", pageData));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(new ApiResponse<>(false, "获取产品列表失败: " + e.getMessage(), null));
        }
    }

    /**
     * 将Product实体转换为ProductDTO
     * @param product 产品实体
     * @return ProductDTO
     */
    private ProductDTO convertToDTO(Product product) {
        ProductDTO dto = new ProductDTO();
        dto.setId(product.getId());
        dto.setProductName(product.getProductName());  // 映射name到productName
        dto.setProductCode(product.getProductCode());
        dto.setBatchNumber(product.getBatchNumber());
        dto.setCategory(product.getCategory());
        dto.setSpecification(product.getSpecification());
        dto.setUnit(product.getUnit());
        dto.setImageUrl(product.getProductImage());

        // 添加缺失的字段映射
        // 处理日期字段 - 转换为字符串格式
        if (product.getPlantingDate() != null) {
            dto.setPlantingDate(product.getPlantingDate().toString());
        }
        if (product.getHarvestDate() != null) {
            dto.setHarvestDate(product.getHarvestDate().toString());
        }

        // 添加其他字段
        dto.setPlantingArea(product.getPlantingArea());
        dto.setQualityLevel(product.getQualityLevel());
        dto.setStorageMethods(product.getStorageMethods());
        dto.setFertilizerUsed(product.getFertilizerUsed());
        dto.setPesticideUsed(product.getPesticideUsed());
        dto.setProductionStandard(product.getProductionStandard());

        // 设置一个默认价格，实际应用中应该从其他表获取或使用其他业务逻辑
        dto.setPrice(99.99);

        return dto;
    }

    /**
     * 获取产品详情
     * @param id 产品ID
     * @return 产品详情
     */
    @GetMapping("/{id}")
    @OperationLog(module = "产品管理", action = "查询", description = "获取产品详情")
    public ResponseEntity<?> getProductById(@PathVariable Long id) {
        try {
            return productRepository.findById(id)
                    .map(ResponseEntity::ok)
                    .orElse(ResponseEntity.notFound().build());
        } catch (Exception e) {
            Map<String, Object> errorResponse = createErrorMap(e.getMessage());
            return ResponseEntity.badRequest().body(errorResponse);
        }
    }

    /**
     * 添加产品
     * @param userId 用户ID
     * @param product 产品信息
     * @return 保存的产品
     */
    @PostMapping("/user/{userId}")
    @OperationLog(module = "产品管理", action = "新增", description = "添加产品")
    public ResponseEntity<?> addProduct(
            @PathVariable Long userId,
            @RequestBody Product product) {
        try {
            // 调试日志
            System.out.println("接收到的产品数据: " + product);
            System.out.println("产品名称: " + product.getProductName());
            System.out.println("批次号: " + product.getBatchNumber());
            
            // 增强参数验证，同时检查productName和name字段
            if ((product.getProductName() == null || product.getProductName().trim().isEmpty())) {
                Map<String, Object> errorMap = createErrorMap("添加产品失败: 产品名称不能为空");
                return ResponseEntity.badRequest().body(errorMap);
            }
            
            if (product.getBatchNumber() == null || product.getBatchNumber().trim().isEmpty()) {
                Map<String, Object> errorMap = createErrorMap("添加产品失败: 批次号不能为空");
                return ResponseEntity.badRequest().body(errorMap);
            }
            
            User user = userRepository.findById(userId)
                    .orElseThrow(() -> new RuntimeException("User not found"));

//            product.setFarmerId(userId);
            product.setFarmerId(11L);
            // 设置时间字段
            LocalDateTime now = LocalDateTime.now();
            if (product.getCreatedAt() == null) {
                product.setCreatedAt(now);
            }
            if (product.getUpdatedAt() == null) {
                product.setUpdatedAt(now);
            }

            // 处理无效的日期格式 - 如果解析失败则使用当前时间
            try {
                if (product.getPlantingDate() == null) {
                    product.setPlantingDate(now);
                }
            } catch (Exception e) {
                // 如果发生任何异常，使用当前时间
                product.setPlantingDate(now);
            }

            try {
                if (product.getHarvestDate() == null) {
                    product.setHarvestDate(now);
                }
            } catch (Exception e) {
                // 如果发生任何异常，使用当前时间
                product.setHarvestDate(now);
            }

            // 自动生成产品编码
            if (product.getProductCode() == null || product.getProductCode().isEmpty()) {
                // 从产品类别获取前缀，默认使用"PD"
                String category = "PD";
                if (product.getCategory() != null && !product.getCategory().isEmpty()) {
                    // 获取类别的前两个字符作为编码前缀
                    if (product.getCategory().length() >= 2) {
                        category = product.getCategory().substring(0, 2);
                    } else {
                        category = product.getCategory();
                    }
                }

                // 使用硬编码年月
                String yearMonth = "202504";

                // 基础编码前缀
                String baseCode = category.toUpperCase() + yearMonth;

                // 获取相同前缀的产品数量
                List<Product> existingProducts = productRepository.findAll().stream()
                        .filter(p -> p.getProductCode() != null && p.getProductCode().startsWith(baseCode))
                        .collect(Collectors.toList());
                int sequence = existingProducts.size() + 1;

                // 完整产品编码: 类别前缀 + 年月 + 4位序列号
                String productCode = baseCode + String.format("%04d", sequence);
                product.setProductCode(productCode);
            }

            Product savedProduct = productRepository.save(product);

            // 记录活动
            FarmingActivity activity = new FarmingActivity();
            activity.setUser(user);
            activity.setType("product");
            activity.setContent("添加了新产品: " + product.getProductName());
            activityRepository.save(activity);

            return ResponseEntity.ok(savedProduct);
        } catch (Exception e) {
            Map<String, Object> errorMap = createErrorMap("添加产品失败: " + e.getMessage());
            return ResponseEntity.badRequest().body(errorMap);
        }
    }

    /**
     * 更新产品
     * @param id 产品ID
     * @param product 产品信息
     * @return 更新后的产品
     */
    @PutMapping("/{id}")
    @OperationLog(module = "产品管理", action = "修改", description = "更新产品信息")
    public ResponseEntity<?> updateProduct(
            @PathVariable Long id,
            @RequestBody Product product) {
        try {
            return productRepository.findById(id)
                    .map(existingProduct -> {
                        product.setId(id);
                        product.setCreatedAt(existingProduct.getCreatedAt());
                        product.setFarmerId(existingProduct.getFarmerId());
                        product.setUpdatedAt(LocalDateTime.now());

                        // 保留原有日期值，如果没有提供新的值
                        if (product.getPlantingDate() == null) {
                            product.setPlantingDate(existingProduct.getPlantingDate());
                        }
                        if (product.getHarvestDate() == null) {
                            product.setHarvestDate(existingProduct.getHarvestDate());
                        }

                        Product updatedProduct = productRepository.save(product);

                        // 获取用户对象用于记录活动
                        User user = userRepository.findById(existingProduct.getFarmerId())
                            .orElseThrow(() -> new RuntimeException("User not found"));

                        // 记录活动
                        FarmingActivity activity = new FarmingActivity();
                        activity.setUser(user);
                        activity.setType("product");
                        activity.setContent("更新了产品: " + product.getProductName());
                        activityRepository.save(activity);

                        return ResponseEntity.ok(updatedProduct);
                    })
                    .orElse(ResponseEntity.notFound().build());
        } catch (Exception e) {
            Map<String, Object> errorResponse = createErrorMap("更新产品失败: " + e.getMessage());
            return ResponseEntity.badRequest().body(errorResponse);
        }
    }

    /**
     * 删除产品
     * @param id 产品ID
     * @return 响应
     */
    @DeleteMapping("/{id}")
    @OperationLog(module = "产品管理", action = "删除", description = "删除产品")
    public ResponseEntity<?> deleteProduct(@PathVariable Long id) {
        try {
            return productRepository.findById(id)
                    .map(product -> {
                        // 获取用户对象用于记录活动
                        User user = userRepository.findById(product.getFarmerId())
                            .orElseThrow(() -> new RuntimeException("User not found"));

                        // 记录活动
                        FarmingActivity activity = new FarmingActivity();
                        activity.setUser(user);
                        activity.setType("product");
                        activity.setContent("删除了产品: " + product.getProductName());
                        activityRepository.save(activity);

                        productRepository.deleteById(id);
                        return ResponseEntity.ok().build();
                    })
                    .orElse(ResponseEntity.notFound().build());
        } catch (Exception e) {
            Map<String, Object> errorResponse = createErrorMap("删除产品失败: " + e.getMessage());
            return ResponseEntity.badRequest().body(errorResponse);
        }
    }

    /**
     * 创建错误响应Map
     * @param errorMessage 错误信息
     * @return 错误响应Map
     */
    private Map<String, Object> createErrorMap(String errorMessage) {
        Map<String, Object> errorMap = new HashMap<>();
        errorMap.put("error", errorMessage);
        return errorMap;
    }

    /**
     * 根据农户ID查询产品
     * @param farmerId 农户ID
     * @return 产品列表
     */
    @GetMapping("/farmer/{farmerId}")
    public ResponseEntity<?> getProductsByFarmerId(@PathVariable Long farmerId) {
        try {
            List<Product> products = productRepository.findByFarmerId(farmerId);
            return ResponseEntity.ok(products);
        } catch (Exception e) {
            Map<String, Object> errorMap = createErrorMap("获取产品列表失败: " + e.getMessage());
            return ResponseEntity.badRequest().body(errorMap);
        }
    }

    /**
     * 通过批次ID获取产品
     * @param batchId 批次ID
     * @return 产品列表
     */
    @GetMapping("/batch/{batchId}")
    public ResponseEntity<?> getProductByBatchId(@PathVariable String batchId) {
        try {
            Optional<Product> productOpt = productRepository.findByBatchId(batchId);
            return productOpt.map(ResponseEntity::ok)
                    .orElse(ResponseEntity.notFound().build());
        } catch (Exception e) {
            Map<String, Object> errorMap = createErrorMap("查询产品失败: " + e.getMessage());
            return ResponseEntity.badRequest().body(errorMap);
        }
    }

    /**
     * 获取产品类别列表
     * @return 类别列表
     */
    @GetMapping("/categories")
    public ResponseEntity<?> getProductCategories() {
        try {
            List<String> categories = productRepository.findAll().stream()
                    .map(Product::getCategory)
                    .distinct()
                    .collect(Collectors.toList());
            return ResponseEntity.ok(categories);
        } catch (Exception e) {
            Map<String, Object> errorResponse = createErrorMap("获取产品类别失败: " + e.getMessage());
            return ResponseEntity.badRequest().body(errorResponse);
        }
    }

    /**
     * 获取产品产量排行
     */
    @GetMapping("/yield-ranking")
    public ResponseEntity<?> getProductYieldRanking(@RequestParam(required = false, defaultValue = "month") String timeRange) {
        try {
            // 获取当前用户ID
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            String username = auth.getName();
            User currentUser = userRepository.findByUsername(username)
                    .orElseThrow(() -> new RuntimeException("用户未找到"));

            // 根据时间范围过滤数据
            LocalDateTime startDate;
            LocalDateTime now = LocalDateTime.now();

            switch (timeRange) {
                case "week":
                    startDate = now.minusWeeks(1);
                    break;
                case "year":
                    startDate = now.minusYears(1);
                    break;
                case "month":
                default:
                    startDate = now.minusMonths(1);
                    break;
            }

            // 获取排行数据 - 这里使用模拟数据，实际应替换为查询数据库
            List<Map<String, Object>> yieldRanking = new ArrayList<>();

            // 模拟数据 - 产品产量排行
            yieldRanking.add(createRankingData("特级枸杞", 520));
            yieldRanking.add(createRankingData("有机枸杞", 420));
            yieldRanking.add(createRankingData("中宁枸杞", 380));
            yieldRanking.add(createRankingData("黑枸杞", 320));
            yieldRanking.add(createRankingData("红枸杞", 290));

            // 返回结果
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("data", yieldRanking);

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", e.getMessage());
            return ResponseEntity.badRequest().body(response);
        }
    }

    /**
     * 辅助方法：创建排行数据
     */
    private Map<String, Object> createRankingData(String name, int value) {
        Map<String, Object> data = new HashMap<>();
        data.put("name", name);
        data.put("value", value);
        return data;
    }
}
